package com.demo.util;

import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RBucket;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

/**
 * @author wangfengchen
 */
@Service
@Slf4j
public class IdempotentCheckUtil {

  public static final String IDEMPOTENT_LOCK_KEY = "idempotent_lock:";
  public static final String IDEMPOTENT_CHECK_CACHE_KEY = "idempotent:key:";
  /**
   * 幂等性校验key存放时长 5分钟
   */
  public static final long IDEMPOTENT_CHECK_CACHE_TIME = 5L;

  @Autowired
  private RedissonClient redissonClient;

  /**
   * 幂等校验 ，处理过的返回false 第一次处理的返回true request的缓存时间为5分钟
   *
   * @param requestId
   * @param toAddress
   * @return
   */
  public boolean idempotentCheck(String requestId, String toAddress) {
    RLock lock = redissonClient.getLock(IDEMPOTENT_LOCK_KEY + toAddress);
    try {
      lock.lock();
      log.info("幂等性校验加锁成功，key = {}", IDEMPOTENT_LOCK_KEY + toAddress);
      RBucket<Object> bucket = redissonClient.getBucket(IDEMPOTENT_CHECK_CACHE_KEY + requestId);
      if (bucket.get() == null) {
        bucket.set(requestId, IDEMPOTENT_CHECK_CACHE_TIME, TimeUnit.MINUTES);
        return true;
      }
      return false;
    } finally {
      if (lock.isLocked() && lock.isHeldByCurrentThread()) {
        lock.unlock();
        log.info("邮件幂等性校验解锁成功，toAddress:{}", toAddress);
      }
    }
  }
}
